#pragma once

#include "Association.h"

#include "Property.h"
#include "Type.h"

namespace uml {

const bool Association::isDerived_default_ = false;
void Association::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    Relationship::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(endTypes_, "endTypes", json, errorList);
    isDerived_ = json.value("isDerived").toBool(isDerived_default_);
    JsonSerializable::fromJsonArray(memberEnds_, "memberEnds", json, errorList);
    JsonSerializable::fromJsonArray(navigableOwnedEnds_, "navigableOwnedEnds", json, errorList);
    JsonSerializable::fromJsonArray(ownedEnds_, "ownedEnds", json, errorList);
}

void Association::toJson(QJsonObject& json) {
    Relationship::toJson(json);
    JsonSerializable::toJsonArray(endTypes_, "endTypes", json);
    if (isDerived_ != isDerived_default_) {
        json.insert("isDerived", isDerived_);
    }
    JsonSerializable::toJsonArray(memberEnds_, "memberEnds", json);
    JsonSerializable::toJsonArray(navigableOwnedEnds_, "navigableOwnedEnds", json);
    JsonSerializable::toJsonArray(ownedEnds_, "ownedEnds", json);
}

/// <summary>
/// endTypes getter
/// The Classifiers that are used as types of the ends of the Association.
/// </summary>
vector<shared_ptr<Type>>& Association::endTypes() {
    return endTypes_;
}

/// <summary>
/// isDerived getter
/// Specifies whether the Association is derived from other model elements such as
/// other Associations.
/// </summary>
bool Association::isDerived() const {
    return isDerived_;
}

/// <summary>
/// isDerived setter
/// Specifies whether the Association is derived from other model elements such as
/// other Associations.
/// </summary>
void Association::setIsDerived(bool value) {
    isDerived_ = value;
}

/// <summary>
/// memberEnds getter
/// Each end represents participation of instances of the Classifier connected to
/// the end in links of the Association.
/// </summary>
vector<shared_ptr<Property>>& Association::memberEnds() {
    return memberEnds_;
}

/// <summary>
/// navigableOwnedEnds getter
/// The navigable ends that are owned by the Association itself.
/// </summary>
vector<shared_ptr<Property>>& Association::navigableOwnedEnds() {
    return navigableOwnedEnds_;
}

/// <summary>
/// ownedEnds getter
/// The ends that are owned by the Association itself.
/// </summary>
vector<shared_ptr<Property>>& Association::ownedEnds() {
    return ownedEnds_;
}

} // namespace uml
